package com.yupi.yupao.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yupi.yupao.common.ErrorCode;
import com.yupi.yupao.exception.BusinessException;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 算法工具类
 * @author yupi
 */
@SuppressWarnings({"all"})
public class AlgorithmUtils {

    /**
     * 编辑距离算法（用于计算最相似的两组标签）
     * 原理：https://blog.csdn.net/DBC_121/article/details/104198838
     *
     * @param tagList1:标签集合1
     * @param tagList2:标签集合2
     * @return
     */
    public static int minDistance(List<String> tagList1, List<String> tagList2) {
        int n = tagList1.size();
        int m = tagList2.size();

        if (n * m == 0) {
            return n + m;
        }

        int[][] d = new int[n + 1][m + 1];
        for (int i = 0; i < n + 1; i++) {
            d[i][0] = i;
        }

        for (int j = 0; j < m + 1; j++) {
            d[0][j] = j;
        }

        for (int i = 1; i < n + 1; i++) {
            for (int j = 1; j < m + 1; j++) {
                int left = d[i - 1][j] + 1;
                int down = d[i][j - 1] + 1;
                int left_down = d[i - 1][j - 1];
                if (!Objects.equals(tagList1.get(i - 1), tagList2.get(j - 1))) {
                    left_down += 1;
                }
                d[i][j] = Math.min(left, Math.min(down, left_down));
            }
        }
        return d[n][m];
    }

    /**
     * 编辑距离算法（用于计算最相似的两个字符串）
     * 原理：https://blog.csdn.net/DBC_121/article/details/104198838
     * @param word1
     * @param word2
     * @return
     */
    public static int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();

        if (n * m == 0) {
            return n + m;
        }

        int[][] d = new int[n + 1][m + 1];
        for (int i = 0; i < n + 1; i++) {
            d[i][0] = i;
        }

        for (int j = 0; j < m + 1; j++) {
            d[0][j] = j;
        }

        for (int i = 1; i < n + 1; i++) {
            for (int j = 1; j < m + 1; j++) {
                int left = d[i - 1][j] + 1;
                int down = d[i][j - 1] + 1;
                int left_down = d[i - 1][j - 1];
                if (word1.charAt(i - 1) != word2.charAt(j - 1)) {
                    left_down += 1;
                }
                d[i][j] = Math.min(left, Math.min(down, left_down));
            }
        }
        return d[n][m];
    }

    /**
     * public List<User> matchUsers(long num, HttpServletRequest request) {
     *         QueryWrapper<User> queryWrapper = new QueryWrapper<>();
     *         queryWrapper.isNotNull("tags");
     *         queryWrapper.select("id", "tags");
     *         queryWrapper.last("limit 20");//
     *
     *         User loginUser = getLoginUser(request);
     *         if (loginUser == null) {
     *             throw new BusinessException(ErrorCode.NOT_LOGIN, "请先登录");
     *         }
     *
     *         List<User> userList = this.list(queryWrapper);
     *
     *         String tags = loginUser.getTags();
     *         Gson gson = new Gson();
     *         List<String> tagList = gson.fromJson(tags, new TypeToken<List<String>>() {}.getType());
     *
     *         // 使用 PriorityQueue 来维护固定长度的有序集合，按照分数从小到大排序
     *         PriorityQueue<UserScore> topUsers = new PriorityQueue<>(new Comparator<UserScore>() {
     *             @Override
     *             public int compare(UserScore a, UserScore b) {
     *                 // 分数越低越排在前面
     *                 return Long.compare(a.getScore(), b.getScore());
     *             }
     *         });
     *
     *         for (User user : userList) {
     *             if (StringUtils.isBlank(user.getTags()) || Objects.equals(user.getId(), loginUser.getId())) {
     *                 continue;
     *             }
     *
     *             List<String> userTagList = gson.fromJson(user.getTags(), new TypeToken<List<String>>() {}.getType());
     *             long distance = AlgorithmUtils.minDistance(tagList, userTagList);
     *
     *             // 如果队列未满或当前用户分数更低，添加或替换
     *             if (topUsers.size() < num || distance < topUsers.peek().getScore()) {
     *                 topUsers.add(new UserScore(user, distance));
     *                 if (topUsers.size() > num) {
     *                     topUsers.poll();
     *                 }
     *             }
     *         }
     *
     *         // 获取排序后的用户 ID 列表
     *         List<Long> userIds = new ArrayList<>();
     *         while (!topUsers.isEmpty()) {
     *             userIds.add(topUsers.poll().getUser().getId());
     *         }
     *
     *         // 根据用户 ID 查询完整信息
     *         QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
     *         userQueryWrapper.in("id", userIds);
     *         Map<Long, List<User>> userIdUserListMap = this.list(userQueryWrapper).stream()
     *                 .map(user -> getSafetyUser(user))
     *                 .collect(Collectors.groupingBy(User::getId));
     *
     *         List<User> finalUserList = new ArrayList<>();
     *         for (Long userId : userIds) {
     *             finalUserList.add(userIdUserListMap.get(userId).get(0));
     *         }
     *
     *         return finalUserList;
     *
     *     }
     */

}